<?php 
/**
 * This file is part of DomAr.
 * 
 * DomAr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomAr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomAr.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */


/**
* Basic DomSql Query. Uses DomArDataIterator.
* @package DomAr
* @subpackage Query
*/	
class DomArDataQuery extends DomSqlQuery {
	
	/**
	 * @return DomArDataQuery
	 */
	public static function c() {
		return new DomArDataQuery();
	}
	/**
	 * @return DomArDataIterator
	 */
	public function getIterator() {
		return new DomArDataIterator( $this );
	}
}

/**
* Query that returns objects not data. Uses DomArIterator.
* @package DomAr
* @subpackage Query
*/	
class DomArQuery extends DomSqlQuery {
	
	/**
	 * List is optional. If not set, then loaded objects are not added to this list. List is used to determine what objects have been loaded 
	 * through parent and should be saved.
	 *
	 * @var DomArSet
	 */
	protected $list;
	/**
	 * Classname of object which is expected as result. 
	 * Notice that result might give objects that also extend to this.
	 * 
	 * @var String
	 */
	protected $className;
	/**
	 * Tells iterator, that this query returns data for multiple objects. 
	 * Each object which has different tablename in one row is handled as different object.
	 * 
	 * If you want to return all object in an array don't set mainObjectAlias (or unset it)
	 * 
	 * @var Int
	 */
	protected $loadsMultipleObjects = false;
	/**
	 * This alias is used to determine from which table result object is taken. (Other objects are loaded into memory)
	 * Default is t
	 * @var String
	 */
	protected $mainObjectAlias = 't';
	/**
	 * @param DomArSet $list
	 * @return DomArQuery
	 */
	public static function c( DomArSet $list = NULL ) {
		return new DomArQuery( $list );
	}
	/**
	 * @param DomArSet $list
	 */
	public function __construct( DomArSet $list = NULL ) {
		parent::__construct();
		$this->list = $list;
	}
	/**
	 * @param String $className
	 * @return DomArQuery
	 */
	public function setClassName( $className ) {
		$this->className = $className;
		return $this;
	}
	/**
	 * @see joinProperty
	 * @param String $propertyName
	 * @param String $alias
	 * @return DomArQuery
	 */
	public function leftJoinProperty( $propertyName, $alias ) {
		$this->joinProperty( $propertyName, $alias, 'LEFT JOIN');
		return $this;
	}
	/**
	 * Join object property. This method performs join query that will also load class child.
	 *
	 * @param String $propertyName
	 * @param String $alias
	 * @return DomArQuery
	 */
	public function joinProperty( $propertyName, $alias, $joinType = 'JOIN') {
		$this->loadsMultipleObjects(true);
		if( $this->className === NULL )
			throw new RuntimeException('Query className is not set! Set main table result classname to use this method.');
		
		$this->flushFields()->select('*');
		
		$property = call_user_func(array($this->className, 'getProperty'), $propertyName);

		if( $property->actAsParent == false or $property instanceof DomArOneToMany ) {
			$joinCondition = $this->from['alias'].'.'.$propertyName.' = '.$alias.'.id';
		} else {
			$joinCondition = $alias.'.'.$property->inverse.' = '.$this->from['alias'].'.id';
		}
		
		$this->join( call_user_func(array($property->childClassName,'getDbTable')), $alias, $joinCondition, false, $joinType);
		return $this;
		
	}
	/**
	 * Allow this query to load multiple objects from different tables etc.
	 *
	 * @param Bool $value
	 * @return DomArQuery
	 */
	public function loadsMultipleObjects( $value ) {
		$this->loadsMultipleObjects = (bool)$value;
		return $this;
	}
	/** 
	 * See property mainObjectAlias
	 * 
	 * @param String $value
	 * @return DomArQuery
	 */
	public function setMainObjectAlias( $value ) {
		$this->mainObjectAlias = $value;
		return $this;
	}
	/**
	 * Get Iterator object for this query.
	 * @return DomArIterator
	 */
	public function getIterator() {
		return new DomArIterator( $this, $this->list, $this->alias );
	}
}

?>